package com.jxy.man_media_process.mq;


import com.alibaba.fastjson.JSON;
import com.jxy.edu.domain.media.MediaFile;
import com.jxy.edu.domain.media.MediaFileProcess_m3u8;
import com.jxy.edu.utils.HlsVideoUtil;
import com.jxy.edu.utils.Mp4VideoUtil;
import com.jxy.man_media_process.dao.MediaFileRepository;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author Administrator
 * @version 1.0
 **/
@Component
public class MediaProcessTask {

    @Value("${xc-service-manage-media.ffmpeg-path}")
    String ffmpeg_path;

    //上传文件根目录
    @Value("${xc-service-manage-media.video-location}")
    String serverPath;

    @Autowired
    MediaFileRepository mediaFileRepository;
    //接收视频处理消息进行视频处理
    //containerFactory = "customContainerFactory"，多线程处理，再rabbitMq的配置类中，已配置多线程容器工程
    @RabbitListener(queues="${xc-service-manage-media.mq.queue-media-video-processor}",containerFactory = "customContainerFactory")
    public void receiveMediaProcessTask(String msg) {
        //1、解析消息内容，得到视频ID
        Map map = JSON.parseObject(msg, Map.class);
        String mediaId = (String) map.get("mediaId");
        //2、拿mediaId从数据库查询文件信息
        Optional<MediaFile> mediaFileOptional = mediaFileRepository.findById(mediaId);
        if (!mediaFileOptional.isPresent()){
            //如果没有数据就证明，没有文件没有上传成功。无需处理
            return;
        }

        //取出上传文件的对象信息
        MediaFile mediaFile = mediaFileOptional.get();

        //文件类型
        String fileType = mediaFile.getFileType();
        if(!fileType.equals("avi")){
            //如果上传成功了，如果不是以.avi的格式，就不处理
            mediaFile.setProcessStatus("303004");//无需处理字典代码
            mediaFileRepository.save(mediaFile);
            return ;
        }else{
            //需要处理
            mediaFile.setProcessStatus("303001");//处理中字典代码
            mediaFileRepository.save(mediaFile);
        }

        //3、使用工具类将avi文件生成mp4

        //要处理的视频文件的路径,视频根目录+文件路径+文件名称
        String video_path =serverPath+mediaFile.getFilePath()+mediaFile.getFileName();
        //生成的mp4的文件名称,文件id+后缀
        String mp4_name=mediaFile.getFileId()+".mp4";
        //生成的mp4所在的路径:文件路径+文件名称
        String mp4folder_path = serverPath + mediaFile.getFilePath();

        //用工具类生成MP4
        //1.String ffmpeg_path, 2.String video_path, 3.String mp4_name, 4.String mp4folder_path
        //1.ffmpeg转换软件的路径（顶上已经注入了），2.源视频地址，3.转换后的 mp4文件名称，4.转换后的mp4文件存放目录路径
        Mp4VideoUtil mp4VideoUtil = new Mp4VideoUtil(ffmpeg_path, video_path, mp4_name, mp4folder_path);
        //通过转换方法，得到转换结果,失败了，结果会返回失败日志
        String result = mp4VideoUtil.generateMp4();
        if (result==null||!result.equals("success")){
            //结果不等于成功，就设置处理失败的代码
            mediaFile.setProcessStatus("303003");
            //记录转换失败的日志。
            //hls处理 private MediaFileProcess_m3u8 mediaFileProcess_m3u8; 这个属性，用来记录失败信息
            MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
            mediaFileProcess_m3u8.setErrormsg(result);
            //赋值到上传文件对象信息
            mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
            //更新转换视频格式的信息
            mediaFileRepository.save(mediaFile);
            return;
        }


        //4、将mp4生成m3u8和ts文件
        //String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path
        //mp4视频文件路径
        String mp4_video_path = serverPath+mediaFile.getFilePath()+mp4_name;
        //m3u8文件和ts文件目录
        String m3u8folder_path = serverPath+mediaFile.getFilePath()+"hls/";
        //m3u8文件名称
        String m3u8_name = mediaFile.getFileId()+".m3u8";
        //mp4视频分块
        HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path,mp4_video_path,m3u8_name,m3u8folder_path);
        //开始处理视频
        String resultM3u8 = hlsVideoUtil.generateM3u8();
        if (resultM3u8==null||!resultM3u8.equals("success")){
            //结果不等于成功，就设置处理失败的代码
            mediaFile.setProcessStatus("303003");
            //记录转换失败的日志。
            //hls处理 private MediaFileProcess_m3u8 mediaFileProcess_m3u8; 这个属性，用来记录失败信息
            MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
            mediaFileProcess_m3u8.setErrormsg(resultM3u8);
            //赋值到上传文件对象信息
            mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
            //更新转换视频格式的信息
            mediaFileRepository.save(mediaFile);
            return;
        }
        //处理成功
        //获取ts文件列表
        List<String> ts_list = hlsVideoUtil.get_ts_list();
        //设置处理成功的值
        mediaFile.setProcessStatus("303002");
        //把得到的列表设置经属性
        MediaFileProcess_m3u8 mediaFileProcess_m3u8 = new MediaFileProcess_m3u8();
        mediaFileProcess_m3u8.setTslist(ts_list);
        //设置进上传文件对象
        mediaFile.setMediaFileProcess_m3u8(mediaFileProcess_m3u8);
        //保存fileUrl（此url就是视频播放的相对路径）,路径+hls+文件名称
        String fileUrl = mediaFile.getFilePath()+"hls/"+m3u8_name;
        //设置视频播放的相对路径
        mediaFile.setFileUrl(fileUrl);
        //设置好后保存，对象
        mediaFileRepository.save(mediaFile);

    }

}
